; ARM assembler for MD5 algorithm.
; Well, more precisely for MD5Transform.

	AREA |A$$Code|, CODE, READONLY
	EXPORT MD5Transform

; The magic numbers MD5 uses:
table	; First block.
	DCD &d76aa478, &e8c7b756, &242070db, &c1bdceee
	DCD &f57c0faf, &4787c62a, &a8304613, &fd469501
	DCD &698098d8, &8b44f7af, &ffff5bb1, &895cd7be
	DCD &6b901122, &fd987193, &a679438e, &49b40821
	; Second block.
	DCD &f61e2562, &c040b340, &265e5a51, &e9b6c7aa
	DCD &d62f105d, &02441453, &d8a1e681, &e7d3fbc8
	DCD &21e1cde6, &c33707d6, &f4d50d87, &455a14ed
	DCD &a9e3e905, &fcefa3f8, &676f02d9, &8d2a4c8a
	; Third block.
	DCD &fffa3942, &8771f681, &6d9d6122, &fde5380c
	DCD &a4beea44, &4bdecfa9, &f6bb4b60, &bebfbc70
	DCD &289b7ec6, &eaa127fa, &d4ef3085, &04881d05
	DCD &d9d4d039, &e6db99e5, &1fa27cf8, &c4ac5665
	; Fourth block.
	DCD &f4292244, &432aff97, &ab9423a7, &fc93a039
	DCD &655b59c3, &8f0ccc92, &ffeff47d, &85845dd1
	DCD &6fa87e4f, &fe2ce6e0, &a3014314, &4e0811a1
	DCD &f7537e82, &bd3af235, &2ad7d2bb, &eb86d391

buf RN 0
in RN 1
a RN 2
b RN 3
c RN 4
d RN 5
ta1 RN 6
ta2 RN 7
ta3 RN 8
ta4 RN 9
tbl RN 10
xx RN 12
yy RN 14
sp RN 13
lr RN 14
pc RN 15

; Here's the magic routine.
; r0 -> 4-word buf
; r1 -> 16-word in
MD5Transform
	STMFD sp!,{c-tbl,lr}
	LDMIA buf,{a,b,c,d}
	ADR tbl,table

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
	EOR xx,c,d
	AND xx,b,xx
	EOR xx,d,xx
	LDR yy,[in,#0]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#25
	; MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
	EOR xx,b,c
	AND xx,a,xx
	EOR xx,c,xx
	LDR yy,[in,#4]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#20
	; MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
	EOR xx,a,b
	AND xx,d,xx
	EOR xx,b,xx
	LDR yy,[in,#8]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#15
	; MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
	EOR xx,d,a
	AND xx,c,xx
	EOR xx,a,xx
	LDR yy,[in,#12]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#10

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
	EOR xx,c,d
	AND xx,b,xx
	EOR xx,d,xx
	LDR yy,[in,#16]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#25
	; MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
	EOR xx,b,c
	AND xx,a,xx
	EOR xx,c,xx
	LDR yy,[in,#20]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#20
	; MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
	EOR xx,a,b
	AND xx,d,xx
	EOR xx,b,xx
	LDR yy,[in,#24]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#15
	; MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
	EOR xx,d,a
	AND xx,c,xx
	EOR xx,a,xx
	LDR yy,[in,#28]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#10

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
	EOR xx,c,d
	AND xx,b,xx
	EOR xx,d,xx
	LDR yy,[in,#32]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#25
	; MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
	EOR xx,b,c
	AND xx,a,xx
	EOR xx,c,xx
	LDR yy,[in,#36]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#20
	; MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
	EOR xx,a,b
	AND xx,d,xx
	EOR xx,b,xx
	LDR yy,[in,#40]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#15
	; MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
	EOR xx,d,a
	AND xx,c,xx
	EOR xx,a,xx
	LDR yy,[in,#44]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#10

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
	EOR xx,c,d
	AND xx,b,xx
	EOR xx,d,xx
	LDR yy,[in,#48]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#25
	; MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
	EOR xx,b,c
	AND xx,a,xx
	EOR xx,c,xx
	LDR yy,[in,#52]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#20
	; MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
	EOR xx,a,b
	AND xx,d,xx
	EOR xx,b,xx
	LDR yy,[in,#56]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#15
	; MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
	EOR xx,d,a
	AND xx,c,xx
	EOR xx,a,xx
	LDR yy,[in,#60]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#10

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
	EOR xx,b,c
	AND xx,d,xx
	EOR xx,c,xx
	LDR yy,[in,#4]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#27
	; MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
	EOR xx,a,b
	AND xx,c,xx
	EOR xx,b,xx
	LDR yy,[in,#24]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#23
	; MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
	EOR xx,d,a
	AND xx,b,xx
	EOR xx,a,xx
	LDR yy,[in,#44]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#18
	; MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
	EOR xx,c,d
	AND xx,a,xx
	EOR xx,d,xx
	LDR yy,[in,#0]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#12

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
	EOR xx,b,c
	AND xx,d,xx
	EOR xx,c,xx
	LDR yy,[in,#20]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#27
	; MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
	EOR xx,a,b
	AND xx,c,xx
	EOR xx,b,xx
	LDR yy,[in,#40]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#23
	; MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
	EOR xx,d,a
	AND xx,b,xx
	EOR xx,a,xx
	LDR yy,[in,#60]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#18
	; MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
	EOR xx,c,d
	AND xx,a,xx
	EOR xx,d,xx
	LDR yy,[in,#16]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#12

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
	EOR xx,b,c
	AND xx,d,xx
	EOR xx,c,xx
	LDR yy,[in,#36]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#27
	; MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
	EOR xx,a,b
	AND xx,c,xx
	EOR xx,b,xx
	LDR yy,[in,#56]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#23
	; MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
	EOR xx,d,a
	AND xx,b,xx
	EOR xx,a,xx
	LDR yy,[in,#12]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#18
	; MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
	EOR xx,c,d
	AND xx,a,xx
	EOR xx,d,xx
	LDR yy,[in,#32]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#12

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
	EOR xx,b,c
	AND xx,d,xx
	EOR xx,c,xx
	LDR yy,[in,#52]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#27
	; MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
	EOR xx,a,b
	AND xx,c,xx
	EOR xx,b,xx
	LDR yy,[in,#8]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#23
	; MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
	EOR xx,d,a
	AND xx,b,xx
	EOR xx,a,xx
	LDR yy,[in,#28]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#18
	; MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
	EOR xx,c,d
	AND xx,a,xx
	EOR xx,d,xx
	LDR yy,[in,#48]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#12

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
	EOR xx,b,c
	EOR xx,xx,d
	LDR yy,[in,#20]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#28
	; MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
	EOR xx,a,b
	EOR xx,xx,c
	LDR yy,[in,#32]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#21
	; MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
	EOR xx,d,a
	EOR xx,xx,b
	LDR yy,[in,#44]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#16
	; MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
	EOR xx,c,d
	EOR xx,xx,a
	LDR yy,[in,#56]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#9

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
	EOR xx,b,c
	EOR xx,xx,d
	LDR yy,[in,#4]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#28
	; MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
	EOR xx,a,b
	EOR xx,xx,c
	LDR yy,[in,#16]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#21
	; MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
	EOR xx,d,a
	EOR xx,xx,b
	LDR yy,[in,#28]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#16
	; MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
	EOR xx,c,d
	EOR xx,xx,a
	LDR yy,[in,#40]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#9

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
	EOR xx,b,c
	EOR xx,xx,d
	LDR yy,[in,#52]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#28
	; MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
	EOR xx,a,b
	EOR xx,xx,c
	LDR yy,[in,#0]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#21
	; MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
	EOR xx,d,a
	EOR xx,xx,b
	LDR yy,[in,#12]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#16
	; MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
	EOR xx,c,d
	EOR xx,xx,a
	LDR yy,[in,#24]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#9

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
	EOR xx,b,c
	EOR xx,xx,d
	LDR yy,[in,#36]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#28
	; MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
	EOR xx,a,b
	EOR xx,xx,c
	LDR yy,[in,#48]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#21
	; MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
	EOR xx,d,a
	EOR xx,xx,b
	LDR yy,[in,#60]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#16
	; MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
	EOR xx,c,d
	EOR xx,xx,a
	LDR yy,[in,#8]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#9

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
	MVN xx,d
	ORR xx,xx,b
	EOR xx,xx,c
	LDR yy,[in,#0]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#26
	; MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
	MVN xx,c
	ORR xx,xx,a
	EOR xx,xx,b
	LDR yy,[in,#28]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#22
	; MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
	MVN xx,b
	ORR xx,xx,d
	EOR xx,xx,a
	LDR yy,[in,#56]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#17
	; MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
	MVN xx,a
	ORR xx,xx,c
	EOR xx,xx,d
	LDR yy,[in,#20]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#11

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
	MVN xx,d
	ORR xx,xx,b
	EOR xx,xx,c
	LDR yy,[in,#48]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#26
	; MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
	MVN xx,c
	ORR xx,xx,a
	EOR xx,xx,b
	LDR yy,[in,#12]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#22
	; MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
	MVN xx,b
	ORR xx,xx,d
	EOR xx,xx,a
	LDR yy,[in,#40]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#17
	; MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
	MVN xx,a
	ORR xx,xx,c
	EOR xx,xx,d
	LDR yy,[in,#4]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#11

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
	MVN xx,d
	ORR xx,xx,b
	EOR xx,xx,c
	LDR yy,[in,#32]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#26
	; MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
	MVN xx,c
	ORR xx,xx,a
	EOR xx,xx,b
	LDR yy,[in,#60]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#22
	; MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
	MVN xx,b
	ORR xx,xx,d
	EOR xx,xx,a
	LDR yy,[in,#24]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#17
	; MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
	MVN xx,a
	ORR xx,xx,c
	EOR xx,xx,d
	LDR yy,[in,#52]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#11

	LDMIA tbl!,{ta1,ta2,ta3,ta4}
	; MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
	MVN xx,d
	ORR xx,xx,b
	EOR xx,xx,c
	LDR yy,[in,#16]
	ADD xx,xx,yy
	ADD xx,xx,ta1
	ADD a,a,xx
	ADD a,b,a,ROR#26
	; MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
	MVN xx,c
	ORR xx,xx,a
	EOR xx,xx,b
	LDR yy,[in,#44]
	ADD xx,xx,yy
	ADD xx,xx,ta2
	ADD d,d,xx
	ADD d,a,d,ROR#22
	; MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
	MVN xx,b
	ORR xx,xx,d
	EOR xx,xx,a
	LDR yy,[in,#8]
	ADD xx,xx,yy
	ADD xx,xx,ta3
	ADD c,c,xx
	ADD c,d,c,ROR#17
	; MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
	MVN xx,a
	ORR xx,xx,c
	EOR xx,xx,d
	LDR yy,[in,#36]
	ADD xx,xx,yy
	ADD xx,xx,ta4
	ADD b,b,xx
	ADD b,c,b,ROR#11

	LDMIA buf,{ta1,ta2,ta3,ta4}
	ADD a,a,ta1
	ADD b,b,ta2
	ADD c,c,ta3
	ADD d,d,ta4
	STMIA buf,{a,b,c,d}

	LDMIA sp!,{c-tbl,pc}

	END
